package com.qumitech.visualnovel.controller.rest;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.qumitech.visualnovel.console.excel.ExportExcel;
import com.qumitech.visualnovel.model.common.BaseRsp;
import com.qumitech.visualnovel.model.common.ResultEnum;
import com.qumitech.visualnovel.model.common.BaseResponse;
import com.qumitech.visualnovel.model.dao.console.*;
import com.qumitech.visualnovel.model.dao.channel.*;
import com.qumitech.visualnovel.pubdef.dto.asa.asaDTO;
import com.qumitech.visualnovel.service.channel.ChannelCPCDataService;
import com.qumitech.visualnovel.service.channel.ChannelDataService;
import com.qumitech.visualnovel.service.ConsoleChannelConfigService;
import com.google.common.collect.ImmutableMap;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;
import java.util.Map;


/**
 * Created by Edison.hu on 18/9/20.
 */
@RestController
@RequestMapping("/api/channel")
public class ChannelDataController {

    @Autowired
    ChannelDataService channelDataService;

    @Autowired
    ConsoleChannelConfigService configService;

    @Autowired
    ChannelCPCDataService channelCPCDataService;

    @RequestMapping(value = "/dataList", method = RequestMethod.GET)
    public JSONObject ChannelList(@RequestParam(value="offset", required=false, defaultValue="0") int offset,
                                  @RequestParam(value="limit", required=false, defaultValue="20") int limit,
                                  @RequestParam(value="appId", required=false) String appId,
                                  @RequestParam(value="channel", required=false) String channel,
                                  @RequestParam(value="startTime", required=false) String startTime,
                                  @RequestParam(value="endTime", required=false) String endTime,
                                  @RequestParam(value="orderType", required=false, defaultValue="DESC") String orderType,
                                  @RequestParam(value="orderBy", required=false, defaultValue="target_date") String orderBy,
                                  @RequestParam(value="channelType", required=false) Integer channelType){
        int count = channelDataService.ChannelDataListCount(startTime, endTime, channel, appId, channelType);
        List<ChannelData> list = channelDataService.ChannelDataList(startTime, endTime, channel, appId, offset,
                limit, orderType, orderBy,channelType);
        JSONObject result = new JSONObject();
        result.put("items", list);
        result.put("count", count);
        result.put("total", channelDataService.ChannelDataStatistic(startTime, endTime, channel, appId, channelType));

        return new BaseResponse<>(result);
    }

    @RequestMapping(value = "/ChannelOptions", method = RequestMethod.GET)
    public JSONObject AppChannelOptions(){
        Map<String, List<String>> list = configService.getConsoleChannelOptions();
        JSONObject result = new JSONObject();
        result.put("items", list);
        return new BaseResponse<>(result);
    }

    @RequestMapping(value = "/sub_channel_options", method = RequestMethod.GET)
    public JSONObject AppSubChannelOptions(@RequestParam(value="second_name", required=false) String secondName){
        List<String> list = configService.listSubChannel(secondName);
        JSONObject result = new JSONObject();
        result.put("items", list);
        return new BaseResponse<>(result);
    }

    @RequestMapping(value = "/diamond/list", method = RequestMethod.GET)
    public JSONObject ChannelDiamondCommission(@RequestParam(value="offset", required=false, defaultValue="0") int offset,
                                               @RequestParam(value="limit", required=false, defaultValue="20") int limit,
                                               @RequestParam(value="channel", required=false) String channel,
                                               @RequestParam(value="startTime", required=false) String startTime,
                                               @RequestParam(value="endTime", required=false) String endTime,
                                               @RequestParam(value="orderType", required=false, defaultValue="DESC") String orderType,
                                               @RequestParam(value="orderBy", required=false, defaultValue="target_date") String orderBy){
        List<String> channelList=null;
        if (!StringUtils.isEmpty(channel)) {
            String[] channels = channel.split(",");
            channelList= Arrays.asList(channels);
        }
        int count = channelDataService.ChannelDiamondCount(startTime, endTime, channelList);
        List<ChannelDiamondDataDO> list = channelDataService.ChannelDiamondList(startTime, endTime, channelList, offset, limit, orderType, orderBy);
        JSONObject result = new JSONObject();
        result.put("items", list);
        result.put("count", count);
        return new BaseResponse<>(result);
    }

    @RequestMapping(value = "/joyCoins/list", method = RequestMethod.GET)
        public JSONObject ChannelJoyCoinsCommission(@RequestParam(value="offset", required=false, defaultValue="0") int offset,
                                               @RequestParam(value="limit", required=false, defaultValue="20") int limit,
                                               @RequestParam(value="channel", required=false) String channel,
                                               @RequestParam(value="startTime", required=false) String startTime,
                                               @RequestParam(value="endTime", required=false) String endTime,
                                               @RequestParam(value="orderType", required=false, defaultValue="DESC") String orderType,
                                               @RequestParam(value="orderBy", required=false, defaultValue="target_date") String orderBy){
        List<String> channelList=null;
        if (!StringUtils.isEmpty(channel)) {
            String[] channels = channel.split(",");
            channelList= Arrays.asList(channels);
        }
        int count = channelDataService.ChannelJoyCoinsCount(startTime, endTime, channelList);
        List<ChannelJoyCoinsDataDO> list = channelDataService.ChannelJoyCoinsList(startTime, endTime, channelList, offset, limit, orderType, orderBy);
        JSONObject result = new JSONObject();
        result.put("items", list);
        result.put("count", count);
        return new BaseResponse<>(result);
    }

    @RequestMapping(value = "/recharge/list", method = RequestMethod.GET)
    public JSONObject ChannelRecharge(@RequestParam(value="offset", required=false, defaultValue="0") int offset,
                                      @RequestParam(value="limit", required=false, defaultValue="20") int limit,
                                      @RequestParam(value="channel", required=false) String channel,
                                      @RequestParam(value="startTime", required=false) String startTime,
                                      @RequestParam(value="endTime", required=false) String endTime,
                                      @RequestParam(value="orderType", required=false, defaultValue="DESC") String orderType,
                                      @RequestParam(value="orderBy", required=false, defaultValue="target_date") String orderBy){
        List<String> channelList=null;
        if (!StringUtils.isEmpty(channel)) {
            String[] channels = channel.split(",");
            channelList= Arrays.asList(channels);
        }
        int count = channelDataService.ChannelRechargeCount(startTime, endTime, channelList);
        List<ChannelRechargeDataDO> list = channelDataService.ChannelRechargeList(startTime, endTime, channelList,
                offset, limit, orderType, orderBy);
        JSONObject result = new JSONObject();
        result.put("items", list);
        result.put("count", count);
        return new BaseResponse<>(result);
    }

    @RequestMapping(value = "/ChannelCPCOptions", method = RequestMethod.GET)
    public BaseRsp ChannelCPCOptions(){
        JSONArray items = JSONArray.parseArray("[" +
                "{\"id\": \"bili\", \"text\": \"哔哩哔哩\"}," +
                "{\"id\": \"huya\", \"text\": \"虎牙\"}," +
                "{\"id\": \"aisi\", \"text\": \"爱思助手\"}," +
                "{\"id\": \"zuiyou\", \"text\": \"最右\"}," +
                "{\"id\": \"baidu\", \"text\": \"百度\"}," +
                "{\"id\": \"tencent\", \"text\": \"腾讯广点通\"}" +
                "]");
        return new BaseRsp(ResultEnum.SUCCESS, ImmutableMap.of("option", items));
    }

    @RequestMapping(value = "/cpc/dataList", method = RequestMethod.GET)
    public JSONObject ChannelCPCList(@RequestParam(value="offset", required=false, defaultValue="0") int offset,
                                     @RequestParam(value="limit", required=false, defaultValue="20") int limit,
                                     @RequestParam(value="appId", required=false) String appId,
                                     @RequestParam(value="channel", required=false) String channel,
                                     @RequestParam(value="startTime", required=false) String startTime,
                                     @RequestParam(value="endTime", required=false) String endTime,
                                     @RequestParam(value="orderType", required=false, defaultValue="DESC") String orderType,
                                     @RequestParam(value="orderBy", required=false, defaultValue="target_date") String orderBy) {
        int count = channelCPCDataService.ChannelCPCDataListCount(startTime, endTime, channel, appId);
        List<ChannelCPCStatistics> list = channelCPCDataService.ChannelCPCDataList(startTime, endTime, channel, appId,
                offset, limit, orderType, orderBy);
        JSONObject result = new JSONObject();
        result.put("items", list);
        result.put("count", count);

        return new BaseResponse<>(result);
    }

    @RequestMapping(value = "/cpc/recharge/list", method = RequestMethod.GET)
    public JSONObject ChannelCPCRechargeList(@RequestParam(value="offset", required=false, defaultValue="0") int offset,
                                             @RequestParam(value="limit", required=false, defaultValue="20") int limit,
                                             @RequestParam(value="appId", required=false) String appId,
                                             @RequestParam(value="channel", required=false) String channel,
                                             @RequestParam(value="startTime", required=false) String startTime,
                                             @RequestParam(value="endTime", required=false) String endTime,
                                             @RequestParam(value="orderType", required=false, defaultValue="DESC") String orderType,
                                             @RequestParam(value="orderBy", required=false, defaultValue="target_date") String orderBy) {
        int count = channelCPCDataService.ChannelCPCRechargeCount(startTime, endTime, channel, appId);
        List<ChannelCPCRechargeData> list = channelCPCDataService.ChannelCPCRechargeList(startTime, endTime, channel,
                appId, offset, limit, orderType, orderBy);
        JSONObject result = new JSONObject();
        result.put("items", list);
        result.put("count", count);

        return new BaseResponse<>(result);
    }

    // 市场投放数据
    @RequestMapping(value="/launchData", method = RequestMethod.GET)
    @ExportExcel(itemKeys = {"targetDate","channel","expense","downloadCount","activatedCount","activateRate","activateCost","promoteCount",
            "redirectCount","xiaohaoCount","buyCount","registerCount","registerRate","registerCost","remainCount","remainRate",
            "newRechargeHeadCount","recentRechargeHeadCount","newRechargePayCount","weeklyRechargePayCount", "monthlyRechargePayCount","rechargeRate",
            "rechargeCost","totalRechargePayCount","newDiamondHeadCount","newDiamondPayCount","weeklyDiamondPayCount",
            "monthlyDiamondPayCount","newHicoinPayCount","weeklyHicoinPayCount","monthlyHicoinPayCount","consume",
            "weeklyConsume","monthlyConsume","firstDayConsumeROI","secondDayConsumeROI","thirdDayConsumeROI",
            "fourthDayConsumeROI","fifthDayConsumeROI","sixthDayConsumeROI","weeklyConsumeROI","monthlyConsumeROI",
            "firstDayROI","weeklyROI","monthlyROI","arpu"},
            itemNames = {"日期","渠道","花费金额","下载","激活","激活率","激活成本","推广用户","引流用户","小号","买量用户",
                    "注册","注册率","注册成本","次留人数","留存率","新增充值人数","近日充值人数","新增首日充值","新增7日充值",
                    "新增30日充值","付费率","付费成本","当日总充值","新增消耗钻石人数","新用户首日消耗钻石","新用户7日消耗钻石",
                    "新用户30日消耗钻石数","新用户首日消耗嗨币数","新用户7日消耗嗨币数","新用户30日消耗嗨币数","首日消耗",
                    "7日消耗","30日消耗","首日消耗ROI","次日消耗ROI","3日消耗ROI","4日消耗ROI","5日消耗ROI","6日消耗ROI",
                    "7日消耗ROI","30日消耗ROI","新用户首日ROI","新用户7日ROI","新用户30日ROI","新用户首日ARPU值"},
            listKey = "items")
    public JSONObject LaunchDataList(@RequestParam(value="offset", required=false, defaultValue="0") int offset,
                                     @RequestParam(value="limit", required=false, defaultValue="20") int limit,
                                     @RequestParam(value="appId", required=false) String appId,
                                     @RequestParam(value="channel", required=false) String channel,
                                     @RequestParam(value="startTime", required=false) String startTime,
                                     @RequestParam(value="endTime", required=false) String endTime,
                                     @RequestParam(value="orderType", required=false, defaultValue="DESC") String orderType,
                                     @RequestParam(value="orderBy", required=false, defaultValue="target_date") String orderBy,
                                     @RequestParam(value="channelType", required=false) Integer channelType,
                                     @RequestParam(value="filter", required=false, defaultValue="1") Integer filter
                                     ) {
        int count = channelDataService.LaunchDataListCount(startTime, endTime, channel, appId, channelType, filter);
        JSONObject result = channelDataService.LaunchDataList(startTime, endTime, channel, appId, offset,
                limit, orderType, orderBy, channelType, filter);
        result.put("count", count);

        return new BaseResponse<>(result);
    }

    // 市场渠道数据
    @GetMapping("/launchChannel")
    public JSONObject getLaunchChannelList(@RequestParam(value="offset", required=false, defaultValue="0") int offset,
                                                        @RequestParam(value="limit", required=false, defaultValue="20") int limit,
                                                        @RequestParam(value="channel", required=false) String channel,
                                                        @RequestParam(value="status", required=false) Integer status,
                                                        @RequestParam(value="startTime", required=false) String startTime,
                                                        @RequestParam(value="endTime", required=false) String endTime,
                                                        @RequestParam(value="orderType", required=false, defaultValue="DESC") String orderType,
                                                        @RequestParam(value="orderBy", required=false, defaultValue="target_date") String orderBy
                                     ) {
        int count = channelDataService.LaunchChannelListCount(startTime, endTime, channel, status);
        List<LaunchChannelData> list = channelDataService.LaunchChannelList(startTime, endTime, channel, status, offset, limit, orderType, orderBy);
        JSONObject result = new JSONObject();
        result.put("count", count);
        result.put("items", list);
        return new BaseResponse<>(result);
    }

    @GetMapping("/launchData/reference")
    public BaseRsp listLaunchConsumeROIReference() {
        return new BaseRsp(ResultEnum.SUCCESS, channelDataService.listConsumeROIReference());
    }

    @PostMapping("/launchChannel")
    public BaseRsp addLaunchChannel(@RequestBody JSONObject param) {
        String channel = param.get("channel") + ":" + param.get("sub_channel");
        int status = channelDataService.addLaunchChannel(channel);
        if (status == 0) {
            return new BaseRsp(100, "当前渠道已在统计中，添加不成功");
        }
        return new BaseRsp(ResultEnum.SUCCESS);

    }

    @PutMapping("/launchChannel/{channel}")
    public BaseRsp cancelLaunchChannelStatistic(@PathVariable String channel) {
        channelDataService.updateLaunchChannelStatus(channel);
        return new BaseRsp(ResultEnum.SUCCESS);
    }

    @GetMapping("/launchExpense")
    public JSONObject getLaunchExpense(@RequestParam(value="startTime", required=false) String startTime,
                                 @RequestParam(value="endTime", required=false) String endTime,
                                 @RequestParam(value="channel", required=false) String channel,
                                 @RequestParam(value="offset", required=false, defaultValue="0") int offset,
                                 @RequestParam(value="limit", required=false, defaultValue="20") int limit,
                                 @RequestParam(value="orderBy", required=false, defaultValue="target_date") String orderBy,
                                 @RequestParam(value="orderType", required=false, defaultValue="DESC") String orderType
                                 ) {
        List<LaunchExpense> list = channelDataService.LaunchExpenseList(startTime, endTime, channel, offset, limit, orderBy, orderType);
        int count = channelDataService.LaunchExpenseListCount(startTime, endTime, channel);
        int code = 201;
        String msg = "当前日期已配置渠道花费";
        if (count == 0) {
            code = 200;
            msg = "OK";
        }
        for (LaunchExpense l: list) {
            if (l.getExpense() == null && l.getDownloadCount() == null) {
                code = 200;
                msg = "OK";
                break;
            }
        }
        JSONObject result = new JSONObject();
        result.put("count", count);
        result.put("items", list);
        return new BaseResponse<>(code, msg, result);
    }

    @PostMapping("/launchExpense")
    public BaseRsp addLaunchExpense(@RequestBody List<LaunchExpense> launchExpenses) {
        channelDataService.updateLaunchExpense(launchExpenses);
        return new BaseRsp(ResultEnum.SUCCESS);
    }

    // asa数据
    @RequestMapping(value="/asaData", method = RequestMethod.GET)
    @ExportExcel(itemKeys = {"target_date", "keyword_id", "keyword_name", "activated_count", "register_count",
            "recharge_count", "first_day_recharge_count", "first_day_recharge_sum", "third_day_recharge_sum",
            "seventh_day_recharge_sum", "pay_rate", "first_day_consume_sum", "third_day_consume_sum",
            "seventh_day_consume_sum"},
            itemNames = {"日期", "关键词ID", "关键词", "激活数", "注册数", "充值人数", "首日充值人数", "首日充值金额",
                    "三日充值金额", "七日充值金额", "新增付费率", "首日消耗钻石", "三日消耗钻石", "七日消耗钻石"},
            listKey = "items")
    public BaseRsp ASADataList(@RequestParam(value="keywordId", required=false) String keywordId,
                                  @RequestParam(value="keywordName", required=false) String keywordName,
                                  @RequestParam(value="startTime", required=false) String startTime,
                                  @RequestParam(value="endTime", required=false) String endTime,
                                  @RequestParam(value="orderType", required=false, defaultValue="DESC") String orderType,
                                  @RequestParam(value="orderBy", required=false, defaultValue="target_date") String orderBy,
                                  @RequestParam(value="offset", required=false, defaultValue="0") int offset,
                                  @RequestParam(value="limit", required=false, defaultValue="20") int limit,
                                  @RequestParam(value="filter", required=false, defaultValue="0") Integer filter
    ) {
        JSONObject result = new JSONObject();
        int count = channelDataService.asaDataListCount(keywordId, keywordName, startTime, endTime, filter);
        List<asaDTO> items = channelDataService.asaDataList(keywordId, keywordName, startTime, endTime, filter, orderType,
                orderBy, offset, limit);
        List<asaDTO> sum = channelDataService.asaDataListListSum(keywordId, keywordName, startTime, endTime, filter);
        result.put("sum", sum);
        result.put("items", items);
        result.put("count", count);

        return new BaseRsp(ResultEnum.SUCCESS, result);
    }

}
